fix(checker): avoid crash for constrained unpacked args - #21908
fix(checker): avoid crash for constrained unpacked args#21908daleselaji-dev wants to merge 1 commit into
Conversation
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
|
Can confirm that the issue reported by me in #21907 specifically is resolved in this branch (same machine, file that crashed previously is fine with your changes here). (I am not able to test this for other side effects or regressions at this time but looks like mypy_primer and other tools cover that.) Thanks so much! |
|
(It is not clear to me though why store_argument_type is being called in that case though for that type. Will be interesting to see what the team members say. This might not fix all the bugs at the very least since the problem may be in the invoking loop, though this stops it from exceeding the array bound in this particular function. Thanks though, this does fix it without immediate obvious problems!) |
Problem
A constrained generic function whose
*argsannotation contains an unpacked concrete tuple can crash mypy withIndexError: list index out of rangeduring function checking.Root Cause
Expanding constrained type variables turns
Unpack[Tuple[int, float]]into synthetic positional entries in theCallableType, but the copiedFuncItemstill contains only the original*argsAST argument.store_argument_type()indexed the AST argument list using every expanded callable entry.Solution
Ignore expanded callable entries that have no corresponding AST argument. The original variadic argument is still stored normally before expansion, while synthetic entries no longer overwrite it or index past the AST list.
Changes
store_argument_type()for synthetic expanded arguments.Testing
master(b974556f): the issue reproducer raisedIndexErrorand reportedINTERNAL_ERROR.py -3.10 -m pytest 'mypy/test/testcheck.py::TypeCheckSuite::check-generics.test' -q: 197 passed, 2 skipped.py -3.10 -m black --check mypy/types_utils.py: passed.py -3.10 -m ruff check mypy/types_utils.py: passed.py -3.10 -m compileall -q mypy/types_utils.py: passed.py -3.10 -m mypy --config-file mypy_self_check.ini -p mypy: 196 source files passed.git diff --check: passed.Compatibility/Risk
The change affects only type storage during function checking and does not alter accepted type syntax or runtime behavior. Expanded synthetic arguments are skipped because they have no AST variable to receive a type; existing generic regression tests remain green.
Notes for Reviewer
The regression is reproduced with the Python 3.10-compatible spelling
Unpack[Tuple[int, float]]; it exercises the same expanded callable shape as the Python 3.13 syntax in the issue. I first tried matching expanded entries by argument name, but that caused two existing generic tests to regress, so the final patch uses the narrower bounds-only guard.Linked Issue
Fixes #21907